#include "Sock.hpp"
#include <poll.h>

const int num = 1024;
struct pollfd fdsArray[num];

void HandleEvent(int listenSock)
{
    for (int i = 0; i < num; ++i)
    {
        if (fdsArray[i].fd == DEL)
        {
            continue;
        }
        if (fdsArray[i].fd == listenSock)
        {
            if (fdsArray[i].revents == POLLIN)
            {
                int clientfd;
                string clientip;
                uint16_t clientport;
                clientfd = Sock::Accept(listenSock, clientip, clientport);
                if (clientfd < 0)
                {
                    return;
                }
                cout << "获取新连接成功: " << clientip << ":" << clientport << endl;
                int j = 0;
                for (; j < num; ++j)
                {
                    if (fdsArray[j].fd == DEL)
                    {
                        break;
                    }
                }
                if (j == num)
                {
                    cout << "服务器已满" << endl;
                    close(clientfd);
                }
                else
                {
                    fdsArray[j].fd = clientfd;
                    fdsArray[j].events = POLLIN;
                    fdsArray[j].revents = 0;
                }
            }
        }
        // 普通io
        else
        {
            if (fdsArray[i].revents == POLLIN)
            {
                char buffer[1024];
                ssize_t s = read(fdsArray[i].fd, buffer, sizeof(buffer) - 1);
                if (s > 0)
                {
                    buffer[s] = '\0';
                    printf("[%d]: %s", fdsArray[i].fd, buffer);
                }
                else
                {
                    printf("[%d]退出\n", fdsArray[i].fd);
                    close(fdsArray[i].fd);
                    fdsArray[i].fd = DEL;
                }
            }
        }
    }
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        return 1;
    }
    int listenSock = Sock::Socket();
    Sock::Bind(listenSock, atoi(argv[1]));
    Sock::Listen(listenSock);
    for (int i = 1; i < num; ++i)
    {
        fdsArray[i].fd = DEL;
        fdsArray[i].events = 0;
        fdsArray[i].revents == 0;
    }
    fdsArray[0].fd = listenSock;
    fdsArray[0].events = POLLIN;
    while (true)
    {
        int n = poll(fdsArray, num, 1000);
        switch (n)
        {
        case 0:
            cout << "time out..." << (unsigned int)time(nullptr) << endl;
            break;
        case -1:
            cerr << errno << ":" << strerror(errno) << endl;
            break;
        default:
            HandleEvent(listenSock);
        }
    }
    return 0;
}
